<?php

namespace App\Trip\Orders\BookOrders\Train\Passengers\AbstractOrderPassenger;

use App\Models\Train\TrainSeat\Repositories\Interfaces\TrainSeatRepositoryInterface;
use App\Models\Train\TrainSeatInfo\Repositories\Interfaces\TrainSeatInfoRepositoryInterface;
use App\Trip\Train\Seat\Seats;
use App\Trip\Train\TrainInfo\TrainInfo;
use Exception;

abstract class AbstractOrderPassengers
{

    public abstract function buildPassengers(): array;

    /**
     * 获取 下单或改签 乘客构造公共部分
     *
     * @param TrainInfo  $train_info
     * @param Seats      $current_seat
     * @param mixed      $passengers
     * @param int|string $pk
     * @param mixed      $passenger_type
     *
     * @return array|mixed
     * @throws Exception
     */
    protected function getPassengersCommonData(TrainInfo $train_info, Seats $current_seat, mixed $passengers, int|string $pk, mixed $passenger_type): mixed
    {
        $passengers[$pk]['price_details'] = [];
        $passengers[$pk]['seat_name']     = $current_seat->getName();
        $passengers[$pk]['seat_name_uy']  = $current_seat->getNameUy();
        $passengers[$pk]['seat_price']    = $this->calcSeatPriceByPassengerType($train_info, $current_seat, $passenger_type);
        $passengers[$pk]['ticket_price']  = $passengers[$pk]['seat_price'];
        $passengers[$pk]['seat_no']       = '';                                                                                                             // 出票后才有
        $passengers[$pk]['seat_no_uy']    = '';                                                                                                             // 出票后才有
        $passengers[$pk]['ticket_price']  = '';
        return $passengers;
    }

    /**
     * 计算座位票价
     *
     * @throws Exception
     */
    private function calcSeatPriceByPassengerType(TrainInfo $train_info, Seats $current_seat, int $passenger_type): float
    {
        /**
         * 这里要按照 最高价格计算 多退少补
         * 儿童票暂时以成人票价收取，出票后退还差价
         *
         * @var TrainSeatInfoRepositoryInterface $seatInfoRepo
         * @var TrainSeatRepositoryInterface     $seatRepo
         */
        $seatInfoRepo = app(TrainSeatInfoRepositoryInterface::class);
        $seatRepo     = app(TrainSeatRepositoryInterface::class);
        $seats        = $seatInfoRepo->listByTrainCodeAndSeatName(
            $train_info->getTrainCode(),
            $train_info->getFromStationCode(),
            $train_info->getToStationCode(),
            $current_seat->getName(),
        );

        if ($seats->isNotEmpty()) {
            return collect($seats)->max('price');
        } else {
            $seat_info = $seatRepo->findByTrainCodeAndSeatName(
                $train_info->getTrainCode(),
                $train_info->getFromStationCode(),
                $train_info->getToStationCode(),
                $current_seat->getName(),
            );

            if (!$seat_info) {
                throw new Exception("暂时无法获取车次数据，请重试");
            }

            return $seat_info->getSeatPrice();
        }
    }
}